package com.esiran.payadmin.controller;

import com.esiran.payadmin.exception.APIRespException;
import com.esiran.payadmin.model.Order;
import com.esiran.payadmin.service.OrderService;
import com.esiran.payadmin.util.CalendarUtilEx;
import com.esiran.payadmin.util.MapUtilEx;
import com.esiran.payadmin.util.XMLUtil;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Map;

@Controller
@RequestMapping("/api")
public class APIController {
    private static final OkHttpClient okHttpClient;
    private static final Gson gson;
    private final OrderService orderService;
    static {
        okHttpClient = new OkHttpClient();
        gson = new Gson();
    }
    @Autowired
    public APIController(OrderService orderService) {
        this.orderService = orderService;
    }

    @RequestMapping(value = "/callback/wechat",produces = "application/xml;charset=UTF-8")
    public void callbackWechat(
            HttpServletRequest request,
            HttpServletResponse response){

        PrintWriter printWriter = null;
        try {
            printWriter = response.getWriter();
            InputStream is = request.getInputStream();
            BufferedReader bis = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = bis.readLine())!=null){
                sb.append(line.concat("\n"));
            }
            is.close();
            Map<String,String> params = XMLUtil.toMap(sb.toString());
            String returnCode = params.get("return_code");
            if (returnCode.equals("SUCCESS")){
                String outTradeNo = params.get("out_trade_no");
                Order order = orderService.getOrderByNum(outTradeNo);
                if (order!=null&&order.getState().equals(0L)){
                    orderService.updateState(outTradeNo,1L);
                    Order realOrder = orderService.getOrderByNum(outTradeNo);
                    if (realOrder.getNotifyUrl()!=null){
                        callNotify(realOrder);
                    }
                }
            }
            response.setContentType("application/xml");
            response.setCharacterEncoding("UTF-8");
            printWriter.println(WxPayNotifyResponse.success("处理成功!"));
        }catch (Exception e){
            if (printWriter != null){
                printWriter.println(WxPayNotifyResponse.success("处理成功!"));
            }
        }
    }
    @RequestMapping(value = "/callback/alipay")
    @ResponseBody
    public String callbackAlipay(
            HttpServletRequest request,
            HttpServletResponse response,
            @RequestParam Map<String,Object> params){
        // 获取订单状态
        String status = (String) params.get("trade_status");
        if (status!=null&&status.equals("TRADE_SUCCESS")){
            try {
                // 获取回调的支付宝接口定义的外部订单号
                String outTradeNo = (String) params.get("out_trade_no");
                // 根据订单号查询订单
                Order order =  orderService.getOrderByNum(outTradeNo);
                if (order == null){
                    throw new APIRespException("订单不存在",-1000);
                }
                if (!order.getState().equals(0L)){
                    throw new APIRespException("订单已支付或关闭",-100);
                }
                orderService.updateState(outTradeNo,1L);
                order.setState(1L);
                callNotify(order);
            } catch (APIRespException e) {
                e.printStackTrace();
            }
        }
        return "success";
    }
    public static boolean callNotify(Order order){
        if (order == null||order.getNotifyUrl()==null){
            return false;
        }
        System.out.println("----------正在发送回调通知-----------");
        String createTime = CalendarUtilEx.simpleFormat(order.getCreateTime());
        String updateTime = CalendarUtilEx.simpleFormat(order.getUpdateTime());
        FormBody.Builder body = new FormBody.Builder()
                .add("order_num",order.getNum())
                .add("extra_num",order.getExtraId())
                .add("state",order.getState().toString())
                .add("amount",order.getMoney().toString())
                .add("create_time",createTime)
                .add("update_time",updateTime);
        Request request = new Request.Builder()
                .url(order.getNotifyUrl())
                .post(body.build()).build();
        try (Response response = okHttpClient.newCall(request).execute()){
            okhttp3.ResponseBody responseBody = response.body();
            if (responseBody== null){
                throw new APIRespException("响应错误",-1009);
            }
            String respBody = responseBody.string();
            System.out.println("发送状态「成功」：".concat(order.getNotifyUrl()).concat("\n[MSG]:").concat(respBody));
        }catch (IOException|APIRespException e){
            e.printStackTrace();
            System.out.println("发送状态「失败」：".concat(order.getNotifyUrl()).concat("\n[MSG]:").concat(e.getMessage()));
            return false;
        }
        System.out.println("----------发送回调通知结束-----------");
        return true;
    }
}
